package clientCommunicationHandler;

import java.io.BufferedReader;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Vector;

import org.jboss.netty.channel.Channel;

import client.TelnetClient;

public class UserInterfaceMsgHandler {

	public static boolean goingToRemoveModerator = false;
	private final String delimiter = (char)1+"";
	BackStack userViewRequestStack ;
	public UserInterfaceMsgHandler(){
		this.userViewRequestStack = new BackStack();
	}
	public String parserUserMsg(int userRequest , String[] menuInArray){
		String [] userChoice = this.getUserChoise(menuInArray, userRequest);
		return initParse(userChoice);
	}
	/**
	 * 
	 * @param userRequest the number that the user enter in the menu
	 * @param menuInArray the menu that user choose from splited by \n;
	 * @return
	 */
	public String initParse(String[] userChoice){
		String [] tMenuInArray = userChoice;
		String temp = tMenuInArray[1];
		if(!(ClientServerMsgHandler.subForumId.equals("0"))&&!UserInterfaceMsgHandler.goingToRemoveModerator ){
			temp = addNewModerator(temp)+handleBackMsg();
			ClientServerMsgHandler.subForumId = "0";
			return temp;
		}
		if(temp.equalsIgnoreCase("Logout\n")){
			temp = "logout"+delimiter+TelnetClient.userName+delimiter;
			TelnetClient.userPosition.removeAllElements();
		}
		else{
			if(temp.equalsIgnoreCase("Login\n")){
				temp = handleLoginForm();
			}
			else{
				if(temp.equalsIgnoreCase("register\n"))
					temp = handleRegisterForm();
				else{
					if(temp.equalsIgnoreCase("view_Forums\n")){
						temp = handleViewForums();
					}
					else{
						if(temp.equalsIgnoreCase("viewThreads")){
							String threadId = tMenuInArray[2].split(":")[0];
							temp = handleViewThreads(threadId);
						} 
						else{
							if(temp.equalsIgnoreCase("add\n")||temp.equalsIgnoreCase("add")){
								if(TelnetClient.userName != "guest"){
									temp = handleAddNewMsg();
								}
								else{
									System.out.println("you are not login.\n in order to post you must to login\n redirecting to welcomPage... ");
									TelnetClient.menu = TelnetClient.welcom_page;
									TelnetClient.transmitToServer = false;
								}
							}
							else{
								if(temp.equalsIgnoreCase("addPost")){
									temp = handleNewPostMsg(tMenuInArray[2]);

								}
								else{
									if(temp.equalsIgnoreCase("back\n")||temp.equalsIgnoreCase("back")){
										temp = handleBackMsg();
									}
									else{
										if(temp.equalsIgnoreCase("viewSubForum"))
											temp = handleViewSubForum(tMenuInArray[2].split(":")[0]);
										else{
											if(temp.equalsIgnoreCase("add-new-SubForum")||temp.equalsIgnoreCase("add-new-SubForum\n")){
												temp = addNewSubForum();
											}
											else{
												if(temp.equalsIgnoreCase("add-moderator")){
													temp = askForCandidatModerators(tMenuInArray);
												}
												else{
													if(temp.equalsIgnoreCase("deleteSubForum")){
														temp = deleteSubForum(tMenuInArray)+refreshView();
													}
													else{
														if(temp.equalsIgnoreCase("removePost")){
															temp = deleteMsg(tMenuInArray);
														}
														else{
															if(temp.equalsIgnoreCase("remove-moderator")){
																temp = getModerator(tMenuInArray);
															}
															else{
																if(temp.equalsIgnoreCase("remove")){
																	UserInterfaceMsgHandler.goingToRemoveModerator = false;
																	temp = removeModerator(tMenuInArray);
																}
																else{
																	if(temp.equalsIgnoreCase("editPost")){
																		temp = editPost(tMenuInArray);
																	}
																}
															}
														}
													}
												}
											}

										}
									}
								}
							}
						}
					}
				}
			}
		}

		return temp;

	}
	private String editPost(String[] tMenuInArray) {
		String editedMsgId = tMenuInArray[2].split(":")[0];
		ReadNewMsg tMsg = new ReadNewMsg();
		String newMsg = tMsg.readMsgFromUser();
		String sendToServer = buildEditMsg(newMsg,editedMsgId);
		return sendToServer;
	}
	private String buildEditMsg(String newMsg, String editedMsgId) {
		String msgForServer = "editPost"+delimiter+TelnetClient.userName+delimiter+this.getUserPositionInServerFormat()+editedMsgId+delimiter+newMsg+delimiter+"\n\0\n"+refreshView();
		return msgForServer;
	}
	private String removeModerator(String[] tMenuInArray) {
		String userName = TelnetClient.userName;
		String subForumId = ClientServerMsgHandler.subForumId;
		String moderatorName = tMenuInArray[2];
		System.out.println("last view "+refreshView());
		return "removeModerator"+delimiter+userName+delimiter+subForumId+delimiter+moderatorName +delimiter+"\n\0\n"+refreshView();
	}
	private String getModerator(String[] tMenuInArray) {
		String subForumId = tMenuInArray[4];
		String userName = TelnetClient.userName;
		ClientServerMsgHandler.subForumId = subForumId;
		return "getModerators"+delimiter+userName+delimiter+subForumId+delimiter;
		
	}
	private String deleteMsg(String[] tMenuInArray) {
		String msgId = tMenuInArray[2].split(":")[0];
		return "deleteMsg"+delimiter+TelnetClient.userName+delimiter+getUserPositionInServerFormat()+msgId+delimiter+"\n\0\n"+refreshView();
	}
	private String deleteSubForum(String[] tMenuInArray) {
		String subForumId = tMenuInArray[2];
		return "DeleteSubForum"+delimiter+TelnetClient.userName+delimiter+subForumId+delimiter+"\n\0\n"+this.handleBackMsg();
	}
	private String askForCandidatModerators(String[] tMenuInArray) {
		ClientServerMsgHandler.subForumId = tMenuInArray[4];
		String forumId = ClientServerMsgHandler.subForumId;
		return "moderatorsCandidate"+delimiter+TelnetClient.userName+delimiter+forumId+delimiter;
	}
	private String addNewModerator(String temp) {
		return "addModerator"+delimiter+TelnetClient.userName+delimiter+temp+delimiter+ClientServerMsgHandler.subForumId+delimiter+"\n\0\n"+refreshView();
	}
	private String addNewSubForum() {
		String subForumName = "";
		while(subForumName.equals("")){
			System.out.println("please enter sub forum name");
			try {
				subForumName = TelnetClient.in.readLine();
			} catch (IOException e) {
				e.printStackTrace();
				subForumName =  "";
			}
		}
		return "addSubForum"+delimiter+TelnetClient.userName+delimiter+subForumName+delimiter+"\n\0\n"+refreshView();
	}
	private String handleViewSubForum(String userTempPosition) {
		TelnetClient.tempUserNextPosition = userTempPosition;
		String temp = "viewSubForum"+delimiter+userTempPosition+delimiter;
		this.userViewRequestStack.addNewCommand(temp);
		return temp;
	}
	/**
	 * the build the new view thread request form the server and 
	 * add the request to the user view request stack
	 * @param threadId threadId that the user wish to watch
	 * @return server view thread format
	 */
	private String handleViewThreads(String threadId) {
		String temp = BuildViewThreadMsg(threadId);//"viewThread\n"+TelnetClient.SubForumId+"\n"+ tMenuInArray[2].split(":")[0]+"\n\0\n";
		userViewRequestStack.addNewCommand(temp);
		TelnetClient.tempUserNextPosition = threadId;

		return temp;
	}
	/***
	 * build server view forum message 
	 * and add the view request the the user view request stack
	 * reset the user position to view forum form
	 * @return
	 */
	private String handleViewForums() {
		String temp = "viewForum"+delimiter;
		TelnetClient.userPosition = new Vector<String>();
		userViewRequestStack.addNewCommand(temp);
		return temp;
	}
	/**
	 * 
	 * @param menuInArray the menu which the user choose from 
	 * @param userRequest the number which the user choose
	 * @return the user command in array
	 */
	private String[] getUserChoise(String[] menuInArray, int userRequest) {
		return menuInArray[userRequest] .split(" ");
	}
	/**
	 * read new post message
	 * and automatically asking for  refresh view
	 * @param postId the post id which the user want to response to 
	 * @return server message format for adding new post + refresh new view;
	 */
	private String handleNewPostMsg(String postId) {
		ReadNewMsg tMsg = new ReadNewMsg();
		String msg = tMsg.readMsgFromUser();
		String temp = "addPost"+delimiter+TelnetClient.userName+delimiter+msg+delimiter+this.getUserPositionInServerFormat()+postId+delimiter+"\n\0\n"+
				this.refreshLastViewedThread();
		return temp;
	}
	/**
	 * 
	 * @param threadID
	 * @return server viewThread message format 
	 */
	private String BuildViewThreadMsg(String threadID) {
//		delimiter+this.getUserPositionInServerFormat()+
		return "viewThread"+delimiter+threadID+delimiter;
	}
	/**
	 * 
	 * @return last view the server sent.
	 */
	private String handleBackMsg() {
		String temp = this.userViewRequestStack.getLastCommand();
		if (temp.equals("")){
			temp = handleViewForums();
		}
		else{
			TelnetClient.userPosition.remove(TelnetClient.userPosition.size() -1);
		}
		return temp;
	}
	/**
	 * add new message 
	 * @return server format for new message
	 */
	private String handleAddNewMsg() {
		ReadNewMsg tMsg = new ReadNewMsg();
		String msg = tMsg.readMsgFromUser();
		System.out.println("handleAddNewMsg: userPosition is: "+TelnetClient.userPosition);
		String temp = "";
		String userPositionServerFormat = this.getUserPositionInServerFormat();
		if(TelnetClient.userPosition.size() <= 1) {
			temp ="addThread\n"+TelnetClient.userName+delimiter+msg+delimiter+userPositionServerFormat+"\n\0\n" +
					this.refreshLastViewedsubForum();
		}
		else{
			temp = "addPost"+delimiter+TelnetClient.userName+delimiter+msg+delimiter+userPositionServerFormat+"\n\0\n"+ 
					this.refreshLastViewedThread();
		}


		return temp;
	}

	private String getUserPositionInServerFormat() {
		String pos = "";
		for(int i = 0;i<TelnetClient.userPosition.size();i++){
			pos += TelnetClient.userPosition.elementAt(i)+delimiter;
		}
		return pos;
	}
	/**
	 * 
	 * @return user view request
	 */
	private String refreshView(){
		return userViewRequestStack.viewLastCommand();
	}
	/**
	 * @pre TelnetClient.subForumId > 0 ; 
	 * @return the command to watch the last sub forum the user was in 
	 */
	private String refreshLastViewedsubForum(){
		return "viewSubForum"+delimiter+this.getUserPositionInServerFormat()+delimiter;
	}
	/**
	 * @pre TelnetClient.subForumId > 0 && TelnetClient.threadId > 0; 
	 * @return the command to watch the last sub forum the user was in 
	 */
	private String refreshLastViewedThread(){
		return "viewThread"+delimiter+this.getUserPositionInServerFormat();
	}
	/**
	 * 
	 * @param in buffer reader
	 * @return user name
	 */
	private String readUserName(BufferedReader in){
		System.out.println("enter your user name:");
		String tUserName = null;
		while(tUserName == null){
			try {
				tUserName = in.readLine();
				System.out.println("UserIntegerface readFromFile "+ tUserName);
				if(tUserName.equals("")){
					tUserName = null;
					System.out.println("invalid user name please re-enter your user name");		
				}
			} catch (IOException e) {
				e.printStackTrace();
				tUserName = null;
			}
		}
		//save the temporary user name,for future management.
		TelnetClient.tempUserName = tUserName;
		return tUserName;

	}

	/**
	 * 
	 * @param in buffer reader
	 * @return user password
	 */
	private String readUserPass(BufferedReader in){
		Console c = System.console();
		UserProxyPasswordReader pass = new UserProxyPasswordReader();
		pass.setBuffer(in);
		pass.setConsole(c);
		return pass.readPassword();
	}

	/**
	 * read from the user username and user password
	 * @post username != ""
	 * @post password !=""
	 * @return server login message format
	 */
	private String handleLoginForm() {
		//		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		//		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String tUserName = readUserName(TelnetClient.in);
		String tPass = readUserPass(TelnetClient.in);
		String result = createLoginMsg(tUserName, tPass);
		return result;
	}
	public String createLoginMsg(String tUserName, String tPass) {
		String result = "login"+delimiter+tUserName+delimiter+tPass+delimiter;
		if(TelnetClient.userPosition.size() < 1)
			ClientServerMsgHandler.buildMenu = true;
		else{
			ClientServerMsgHandler.buildMenu = false;
			result += refreshView();
		}
		return result;
	}

	/**
	 * read from the user username and user password
	 * @post username != ""
	 * @post password !=""
	 * @return server login message format
	 */

	private  String handleRegisterForm() {
		String tUserName = readUserName(TelnetClient.in);
		String tPass = readUserPass(TelnetClient.in);
		return "register"+delimiter+tUserName+delimiter+tPass+delimiter;
	}

}
